package com.ecnu.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.ecnu.common.config.RuoYiConfig;
import com.ecnu.common.constant.Constants;
import com.ecnu.common.core.domain.AjaxResult;
import com.ecnu.common.core.domain.entity.SysUser;
import com.ecnu.common.core.domain.model.LoginUser;
import com.ecnu.common.core.page.PageDomain;
import com.ecnu.common.core.page.TableDataInfo;
import com.ecnu.common.utils.*;
import com.ecnu.common.utils.http.UrlUtils;
import com.ecnu.common.utils.uuid.IdUtils;
import com.ecnu.system.domain.*;
import com.ecnu.system.domain.dto.ProjectCheckDTO;
import com.ecnu.system.domain.dto.ProjectResultDTO;
import com.ecnu.system.domain.vo.ProjectResultVO;
import com.ecnu.system.mapper.*;
import com.ecnu.system.service.IProjectResultService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static com.ecnu.system.domain.menu.OtherMenu.sysUrl;

/**
 * <p>
 * ecnu_活动_成果表 服务实现类
 * </p>
 *
 * @author zdn
 * @since 2025-03-24
 */
@Service
public class ProjectResultServiceImpl extends ServiceImpl<ProjectResultMapper, ProjectResult> implements IProjectResultService {

    @Autowired
    private ProjectResultMapper projectResultMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private ProjectStageMapper stageMapper;
    @Autowired
    private ProjectStageMissionMapper stageMissionMapper;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private ProjectExcellentMapper excellentMapper;


    /**
     * 分页查询
     */
    protected void startPage(PageDomain pageDomain) {
        PageUtils.startPage(pageDomain);
    }

    protected String getId() {
        return IdUtils.fastSimpleUUID();
    }


    public TableDataInfo list(ProjectResultDTO dto, QueryWrapper<ProjectResult> wrapper, Integer i) {
        try {
            startPage(dto.getPageDomain());//分页
            //取分页数据
            TableDataInfo dataTable = OtherUtil.tableSuccess(projectResultMapper.selectList(wrapper));
            List<ProjectResultVO> resultVOS = OtherUtil.copy(dataTable.getRows(), ProjectResultVO.class);
            //判断是否有数据
            if (!resultVOS.isEmpty()) {
                //获取上传人
                List<String> fileList = resultVOS.stream()
                        .map(ProjectResult::getCreateUser)
                        .collect(Collectors.toList());
                //取信息
                List<SysUser> sysUsers = sysUserMapper.selectBatchIds(fileList);
                Map<Long, SysUser> userMap = sysUsers.stream()
                        .collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
                //补充上传人名
                resultVOS.forEach(a -> {
                    SysUser sysUser = userMap.get(Long.parseLong(a.getCreateUser()));
                    String userVOs = sysUser != null ?
                            sysUser.getNickName() : // 用逗号拼接
                            "";
                    a.setRealName(userVOs);
                });
//                if (i == 1) {
                //获取项目名
//                List<String> stageList = resultVOS.stream()
//                        .map(ProjectResult::getStageId)
//                        .collect(Collectors.toList());
                //任务清单列表
                ObjectMapper objectMapper = new ObjectMapper();
                //获取该活动下的所有任务清单
                LambdaQueryWrapper<ProjectStageMission> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(ProjectStageMission::getStageId, dto.getId());
                List<ProjectStageMission> missions = stageMissionMapper.selectList(queryWrapper);
                List<ProjectCheckDTO> checkDTOs = new ArrayList<>();
                //遍历所有任务清单
                for (ProjectStageMission mission : missions) {
                    List<ProjectCheckDTO> checkDTO2 = ((List<Map<String, Object>>) getList(mission.getCheckList()))
                            .stream()
                            .map(map -> objectMapper.convertValue(map, ProjectCheckDTO.class))
                            .collect(Collectors.toList());
                    checkDTOs.addAll(checkDTO2);
                }
                //做成id+任务的方式
                Map<String, ProjectCheckDTO> psMap = checkDTOs.stream()
                        .collect(Collectors.toMap(ProjectCheckDTO::getId, Function.identity()));
//              补充展示任务名
                resultVOS.forEach(a -> {
                    ProjectCheckDTO projectCheckDTO = psMap.get(a.getStageId());
                    String userVOs = projectCheckDTO != null ?
                            projectCheckDTO.getContent() : // 用逗号拼接
                            "";
                    a.setStageName(userVOs);
                });
                //获取项目名
                List<String> missionList = resultVOS.stream()
                        .map(ProjectResult::getMissionId)
                        .collect(Collectors.toList());
                //取信息
                List<ProjectStageMission> projectStageMissions = stageMissionMapper.selectBatchIds(missionList);
                Map<String, ProjectStageMission> psmMap = projectStageMissions.stream()
                        .collect(Collectors.toMap(ProjectStageMission::getId, Function.identity()));
//                    //补充上传人名
                resultVOS.forEach(a -> {
                    ProjectStageMission projectStageMission = psmMap.get(a.getMissionId());
                    String userVOs = projectStageMission != null ?
                            projectStageMission.getMissionName() : // 用逗号拼接
                            "";
                    a.setMissionName(userVOs);
                });
                resultVOS.forEach(a -> {
                    ProjectExcellent projectExcellent = excellentMapper.selectOne(new LambdaQueryWrapper<ProjectExcellent>()
                            .eq(ProjectExcellent::getResultId, a.getId()));
                    a.setIsExcellent(projectExcellent != null?true:false);
                    a.setFullurl(UrlUtils.getUrl()  + a.getUrl());
                });
            }
//            }
            dataTable.setRows(resultVOS);
            return dataTable;
        } catch (InvocationTargetException | NoSuchMethodException | InstantiationException |
                 IllegalAccessException e) {
            log.error("查询失败：" + e.getMessage());
            TableDataInfo error = OtherUtil.tableError(e.getMessage());
            return error;
        }
    }
    /**
     * string ==> object(json方式的）
     *
     * @param mission
     * @return
     */
    private Object getList(String mission) {
        List<Map> checkLists = new ArrayList<>();
        if (StringUtils.isNotBlank(mission)) {
            try {
                mission = mission
                        .replaceAll("^\"+", "")  // 去除开头引号
                        .replaceAll("\"+$", "")
                        .replaceAll("^\"|\"$", "")
                        .replaceAll("\\\\\"", "\"")
                        .replaceAll("\\\\\\\\", "\\\\");
                checkLists = new ObjectMapper().readValue(mission, List.class);
            } catch (JsonProcessingException e) {
                log.error("JSON解析异常", e);
                return mission;
            }
        }
        return checkLists;
    }
    //    public String getUrl()
//    {
//        HttpServletRequest request = ServletUtils.getRequest();
//        return getDomain(request);
//    }
//    public static String getDomain(HttpServletRequest request)
//    {
//        StringBuffer url = request.getRequestURL();
//        String contextPath = request.getServletContext().getContextPath();
//        return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString();
//    }
    @Override
    public TableDataInfo getList(ProjectResultDTO dto, LoginUser loginUser) {
        QueryWrapper<ProjectResult> wrapper = new QueryWrapper<ProjectResult>()
                .eq("pro_id", dto.getId())
                .eq("del_flag", "0");
        if (loginUser.getUser().getUserId() != 1) {
            wrapper.eq("create_user", loginUser.getUser().getUserId());
        }

        if (StringUtils.isNotBlank(dto.getName())) {
            wrapper.like("name", dto.getName());
        }
        wrapper.orderByDesc("create_time");
        return list(dto, wrapper, 1);
    }

    @Override
    public TableDataInfo adminList(ProjectResultDTO dto) {
        QueryWrapper<ProjectResult> wrapper = new QueryWrapper<ProjectResult>()
                .eq("pro_id", dto.getId())
                .eq("del_flag", "0");
        if (StringUtils.isNotBlank(dto.getName())) {
            wrapper.like("name", dto.getName());
        }
        wrapper.orderByDesc("create_time");
        return list(dto, wrapper, 2);
    }

    @Override
    public AjaxResult save(ProjectResult projectResult, LoginUser loginUser) {
        projectResult.setId(getId());
        projectResult.setCreateUser(loginUser.getUserId().toString());
        projectResult.setStageId(projectResult.getMissionId());
        int insert = projectResultMapper.insert(projectResult);
        return AjaxResult.success("提交成功");
    }

    @Override
    public AjaxResult save2(ProjectResult projectResult, LoginUser loginUser) {
        //1、取当前概览的活动的结束时间
        //2、查询当前时间是否在截止时间前
        //3、如果截止时间前，isPostpone=0,否则isPostpone=1
        ProjectStageMission mission = stageMissionMapper.selectOne(new QueryWrapper<ProjectStageMission>()
                .eq("id", projectResult.getMissionId()));
        ObjectMapper objectMapper = new ObjectMapper();
        if (mission== null) {
            return AjaxResult.error("概览项不存在，请联系管理员调整");
        }

        projectResult.setId(getId());
        projectResult.setCreateUser(loginUser.getUserId().toString());
//        projectResult.setStageId(projectResult.getMissionId());
        //删除以前的数据
        ProjectResult projectResult1 = new ProjectResult();
        projectResult1.setStageId(projectResult.getStageId());
        projectResult1.setProId(projectResult.getProId());
        projectResult1.setMissionId(projectResult.getMissionId());
        projectResult1.setCreateUser(loginUser.getUserId().toString());
        projectResultMapper.updateByStage(projectResult1);
        //int update = projectResultMapper.update(projectResult, new QueryWrapper<ProjectResult>());

        List<ProjectCheckDTO> checkDTOs = ((List<Map<String, Object>>) getList(mission.getCheckList()))
                .stream()
                .map(map -> objectMapper.convertValue(map, ProjectCheckDTO.class))
                .filter(dto->dto.getId().equals(projectResult.getStageId()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(checkDTOs)) {
            Date date = new Date();
            Date date1 = DateUtils.parseDate(checkDTOs.get(0).getEndTime()+" 23:59:59");
            if (date.before(date1)) {
                projectResult.setIsPostpone("0");
            } else {
                projectResult.setIsPostpone("1");
            }
        }else {
            return AjaxResult.error("任务清单项不存在，请联系管理员调整");
        }


        //更新
        int insert = projectResultMapper.insert(projectResult);
        return AjaxResult.success("提交成功");
    }

    @Override
    public byte[] selectFileZip(List<ProjectStageMission> projectStageMissionVOS, String userId, LoginUser loginUser) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        //取得任务id
        List<String> mission = projectStageMissionVOS.stream()
                .map(ProjectStageMission::getId)
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.toList());
        //取得清单列表
        List<String> checkList = projectStageMissionVOS.stream()
                .map(ProjectStageMission::getCheckList)
                .filter(StringUtils::isNotBlank)
                .filter(l-> !l.equals("[]"))
                .collect(Collectors.toList());
        //处理任务清单结构
        List<ProjectCheckDTO> list =new ArrayList<>();
        for (String check : checkList) {
            List<ProjectCheckDTO> checkDTOs = ((List<Map<String, Object>>) getList(check))
                    .stream()
                    .map(map -> objectMapper.convertValue(map, ProjectCheckDTO.class))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(checkDTOs)) {
                list.addAll(checkDTOs);
            }
        }
        Map<String, ProjectCheckDTO> checkDTOMap = list.stream()
                .collect(Collectors.toMap(ProjectCheckDTO::getId, Function.identity()));
        //获取任务清单id
        List<String> stageIds = list.stream()
                .map(ProjectCheckDTO::getId)
                .filter(StringUtils::isNotBlank)
                .filter(l-> !l.equals("[]"))
                .collect(Collectors.toList());
        //获得文件地址之后去文件服务器找对应文件
        QueryWrapper<ProjectResult> wrapper = new QueryWrapper<>();
        wrapper.eq("create_user",userId);
        wrapper.in("mission_id",mission);
        wrapper.in("stage_id",stageIds);
        wrapper.eq("del_flag",0);
        List<ProjectResult> resultList = projectResultMapper.selectList(wrapper);
        // 初始化 ZIP 输出流
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try (ZipOutputStream zip = new ZipOutputStream(outputStream)){
            for (ProjectResult projectResult : resultList) {
                String url = projectResult.getUrl();
                //根据stageID获取任务名称
                ProjectCheckDTO projectCheckDTO = checkDTOMap.get(projectResult.getStageId());
                String localPath = RuoYiConfig.getProfile();
                // 数据库资源地址
                String downloadPath = localPath + StringUtils.substringAfter(url, Constants.RESOURCE_PREFIX);
//                String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
                // 创建文件对象
                File file = new File(downloadPath);
                if (file.exists()) {
                    // 1、创建ZipEntry对象
                    zip.putNextEntry(new ZipEntry(projectCheckDTO.getContent()+"_"+projectResult.getName()));
//                    FileInputStream fis = new FileInputStream(file);
//                    byte[] buffer = new byte[1024];
//                    int len;
//                    while ((len = fis.read(buffer)) > 0) {
//                        zip.write(buffer, 0, len); // 写入 ZIP
//                    }
                    try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
                        byte[] fileBytes = IOUtils.toByteArray(bis);
                        //2、写入ZIP
                        zip.write(fileBytes);
                    }
                    //3、关闭ZIP
                    zip.closeEntry();
//                    fis.close();
                }
            }
            zip.finish();
        }
        //获得文件之后进行打包
        return outputStream.toByteArray();
    }
}
